package com.newpage.module_gather.activity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.newpage.module_gather.R;
import com.newpage.module_gather.R2;
import com.newpage.module_gather.contract.RevisionDrawCon;
import com.newpage.module_gather.presenter.RevisionDrawPre;
import com.tstudy.blepenlib.data.BleDevice;
import com.tstudy.blepenlib.data.CoordinateInfo;
import com.wetao.lib_common.ConstantArouter;
import com.wetao.lib_common.Constants;
import com.wetao.lib_common.base.BaseActivity;
import com.wetao.lib_common.base.BaseResponse;
import com.wetao.lib_common.bean.request.RevisionQuestionReq;
import com.wetao.lib_common.bean.response.RevisionExamQuestionInfo;
import com.wetao.lib_common.bean.response.WrongQuestionInfo;
import com.wetao.lib_common.bean.track.TrackBean;
import com.wetao.lib_common.greendao.DBUtils;
import com.wetao.lib_common.greendao.model.QuestionRevisionItem;
import com.wetao.lib_common.tsdBlePen.TsdPenUtil;
import com.wetao.lib_common.tsdBlePen.TsdService;
import com.wetao.lib_common.utils.BaseEvent;
import com.wetao.lib_common.utils.BitmapUtil;
import com.wetao.lib_common.utils.ComUtil;
import com.wetao.lib_common.utils.DialogXUtil;
import com.wetao.lib_common.utils.FileUtils;
import com.wetao.lib_common.utils.JsonUtils;
import com.wetao.lib_common.utils.LogUtils;
import com.wetao.lib_common.utils.SPUtils;
import com.wetao.lib_common.utils.StringUtil;
import com.wetao.lib_common.utils.ToastUtil;
import com.wetao.lib_common.utils.oss.OssParams;
import com.wetao.lib_common.utils.oss.UploadOss;
import com.wetao.lib_common.view.voicerecorder.EMError;
import com.wetao.lib_common.view.voicerecorder.VoiceRecorder;
import com.wetao.lib_common.view.voicerecorder.VoiceRecorderView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;

import butterknife.BindView;
import butterknife.OnClick;
import cn.hzw.doodle.DoodleColor;
import cn.hzw.doodle.DoodleOnTouchGestureListener;
import cn.hzw.doodle.DoodleParams;
import cn.hzw.doodle.DoodleTouchDetector;
import cn.hzw.doodle.DoodleView;
import cn.hzw.doodle.IDoodleListener;
import cn.hzw.doodle.core.IDoodle;
import cn.hzw.doodle.core.IDoodleItemListener;
import cn.hzw.doodle.core.IDoodleSelectableItem;
import cn.hzw.doodle.core.IDoodleTouchDetector;

/**
 * author: zhouyh
 * created on: 2021/6/23 7:24 下午
 * description:说写订正界面
 */
@Route(path = ConstantArouter.PATH_GATHER_REVISIONDRAWACTIVITY)
public class RevisionDrawActivity extends BaseActivity<RevisionDrawCon.View, RevisionDrawPre> implements RevisionDrawCon.View {


    @Autowired
    int examId;
    @Autowired
    String questionBean;
    @Autowired
    int type;  // 0 错题详情订正  1 订正详情订正

    private static final int DIALOG_TYPE_CLOSE = 701;
    private static final int DIALOG_TYPE_AGAIN = 702;
    private static final int DIALOG_TYPE_COMPLETE = 703;
    private static final int DIALOG_TYPE_RETURN = 704;
    private static final int DIALOG_TYPE_MAXTIME = 705;


    //错题订正
    @BindView(R2.id.rl_revision_record)
    RelativeLayout rl_revision_record;
    @BindView(R2.id.iv_revision_playOrPause)
    ImageView iv_revision_playOrPause;
    @BindView(R2.id.fl_revision_doodle)
    FrameLayout fl_revision_doodle;
    @BindView(R2.id.tv_revision_Time)
    TextView tv_revision_Time;
    @BindView(R2.id.tv_revision_cancel)
    TextView tv_revision_cancel;
    @BindView(R2.id.tv_revision_finish)
    TextView tv_revision_finish;
//    @BindView(R2.id.tv_revision_hint)
//    TextView tv_revision_hint;

    private Bitmap doodle_bitmap;
    private Bitmap small_bitmap;
    private DoodleParams mDoodleParams;
    private IDoodle mDoodle;
    private DoodleView mDoodleView;
    private DoodleOnTouchGestureListener mTouchGestureListener;
    //当前PageID
    private String curPageAddress;

    /**
     * 蓝牙笔
     */
    private boolean isSubmiting;
    private volatile int mSubmitCount = 0;  //记录上传文件数量
    private CoordinateInfo mCurDot;//当前正在绘制的点；
    private ConcurrentLinkedQueue<CoordinateInfo> mOffLineDots = new ConcurrentLinkedQueue();
    private ConcurrentLinkedQueue<CoordinateInfo> mSaveLineDots = new ConcurrentLinkedQueue();
    private float mTemp_x = 0f; //暂存转换后的坐标
    private float mTemp_y = 0f;
    private float m_tran_x = 0f; //轨迹移动的坐标
    private float m_tran_y = 0f; //轨迹移动的坐标
    private boolean isMove = false; //是否笔是移动中

    private double m_scale = 1.41;//点阵纸宽高比  高:宽=1.41
    private int mPic_w = 2149;
    private int mPic_h = 3023;
    private boolean mIsTran_x = false; //是否允许滚动
    private boolean mIsTran_y = false;  //是否允许滚动


    //说写订正录制
    protected PowerManager.WakeLock wakeLock;
    protected int mMaxTime = 10 * 60 * 1000;
    protected VoiceRecorder voiceRecorder;
    private String voiceDirPath;
    private String voiceFilePath; //音频文件地址
    private String trackFilePath; //笔迹文件地址
    private int mRecorderTime;
    private int trackId = 0;
    private int fl_width;
    private int fl_height;
    private int fl_cur_height; //画布当前高度
    private String ossTxtPath;
    private String ossMp3Path;

    private boolean isSubmitSuccess = false;
    private boolean isHasTrack = false;  //是否有笔记


    private RevisionExamQuestionInfo.Data.QuestionListBean curRevisionQuestion;
    private WrongQuestionInfo.Data curWrongQuestion;
    private Integer questionId;
    private Integer studentExamAnswerId;
    private Integer subjectId;

    private WriteThread writeThread;
    private boolean stopWrite = false;

    private MyHandler handler;

    static class MyHandler extends Handler {
        WeakReference<RevisionDrawActivity> weakReference;

        public MyHandler(RevisionDrawActivity activity) {
            weakReference = new WeakReference(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            if (weakReference.get() == null) {
                return;
            }
            RevisionDrawActivity activity = weakReference.get();
            if (msg.what == VoiceRecorderView.HANDLER_VOLUME) {
                activity.onSetVolume(msg.arg1, msg.arg2);
            }
        }
    }


    @Override
    public int getLayoutId() {
        return R.layout.gather_revision_write;
    }

    @Override
    public RevisionDrawPre createPresenter() {
        return new RevisionDrawPre(this);
    }

    @Override
    public RevisionDrawCon.View createView() {
        return this;
    }

    @SuppressLint("InvalidWakeLockTag")
    @Override
    public void init() {
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        handler = new MyHandler(this);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (questionBean != null) {
            if (type == Constants.TYPE_1) {
                curWrongQuestion = WrongQuestionInfo.Data.objectFromData(questionBean);
                questionId = curWrongQuestion.getQuestionId();
                studentExamAnswerId = curWrongQuestion.getStudentExamAnswerId();
                subjectId = curWrongQuestion.getSubjectId();
            } else {
                curRevisionQuestion = RevisionExamQuestionInfo.Data.QuestionListBean.objectFromData(questionBean);
                questionId = curRevisionQuestion.getQuestionId();
                studentExamAnswerId = curRevisionQuestion.getStudentExamAnswerId();
                subjectId = curRevisionQuestion.getSubjectId();
            }

        }

        //开启保存笔迹线程
        writeThread = new WriteThread();
        writeThread.start();

       ToastUtil.initToast("请使用点阵笔在点阵作答本上书写");

        voiceRecorder = new VoiceRecorder(handler);
        initData();

        fileOperate();


    }

    @OnClick({R2.id.iv_revision_playOrPause, R2.id.tv_revision_cancel, R2.id.tv_revision_finish})
    public void onClick(View view) {
        int mId = view.getId();
        if (mId == R.id.iv_revision_playOrPause) {
            recordRevision();
        } else if (mId == R.id.tv_revision_cancel) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    show_btn_dialog(DIALOG_TYPE_CLOSE);
                }
            });
        } else if (mId == R.id.tv_revision_finish) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    show_btn_dialog(DIALOG_TYPE_COMPLETE);
                }
            });

        }
    }


    private TsdService.OnDataReceiveListener tsdListener = new TsdService.OnDataReceiveListener() {
        @Override
        public void onErrTsdPen(int code, String msg) {

        }

        @Override
        public void onRefreshScan(boolean isScaning) {

        }

        @Override
        public void onAddDevice(BleDevice bleDevice) {

        }

        @Override
        public void onPenConnectStatus(int code, BleDevice bleDevice) {

        }

        @Override
        public void onGetPenInfo(int batteryPercent, int memoryPercent, int memoryByteNum) {

        }

        @Override
        public void onFinish() {

        }

        @Override
        public void onTeacherExitSmallTest() {

        }

        @Override
        public void onCoordDraw(CoordinateInfo coordinateInfo) {
            if (voiceRecorder.getRecordStatus() != VoiceRecorder.VOICE_RECORDER_START){
                ToastUtil.initToast("请开始录制再进行书写");
                return;
            }
            if (isSubmiting) {
                return;
            }
            //只允许一张纸作答
            mCurDot = coordinateInfo;
            if (mCurDot.state == TsdService.PEN_DOWN_MESSAGE) {
                LogUtils.i("answerActivity" + ":pageAddress =" + curPageAddress);
                if (curPageAddress == null) {
                    curPageAddress = mCurDot.pageAddress;
                } else if (!mCurDot.pageAddress.equals(curPageAddress)) {
                    ToastUtil.initToast("请在同一页作答");
                    return;
                }
            }

            mOffLineDots.offer(coordinateInfo);
            mSaveLineDots.offer(coordinateInfo);
            nextDots();

        }

    };



    private void nextDots() {
        while (!mOffLineDots.isEmpty()) {
            mCurDot = mOffLineDots.poll();
            scrollBitmap();
            drawBitmap();
        }
    }






    @SuppressLint("InvalidWakeLockTag")
    private void initData() {
        wakeLock = ((PowerManager) getSystemService(Context.POWER_SERVICE)).newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, "voice");

        fl_revision_doodle.post(() -> {
            fl_width = fl_revision_doodle.getMeasuredWidth();
            fl_height = fl_revision_doodle.getMeasuredHeight();

            small_bitmap = BitmapUtil.ReadBitmapById_4444(this, R.drawable.doodle_bk);
            doodle_bitmap = resizeImage(small_bitmap, fl_width, (int) (fl_width * m_scale));

            fl_cur_height = fl_height;
            LogUtils.i("fl_doodle的宽：" + fl_width + ", 高" + fl_height +
                    ",bitmap宽：" + doodle_bitmap.getWidth()+",高："+doodle_bitmap.getHeight() + ",curHeight=" + fl_cur_height);

            initDoodleData();


        });



    }


    /**
     * 初始化涂鸦
     */
    private void initDoodleData() {
        fl_revision_doodle.removeAllViews();
        mDoodleParams = new DoodleParams();
        mDoodleParams.mSavePathIsDir = false;
        mDoodleParams.mIsDrawableOutside = false;

        /*
        Whether or not to optimize drawing, it is suggested to open, which can optimize the drawing speed and performance.
        Note: When item is selected for editing after opening, it will be drawn at the top level, and not at the corresponding level until editing is completed.
        是否优化绘制，建议开启，可优化绘制速度和性能.
        注意：开启后item被选中编辑时时会绘制在最上面一层，直到结束编辑后才绘制在相应层级
         */
        mDoodle = mDoodleView = new DoodleViewWrapper(this, doodle_bitmap, mDoodleParams.mOptimizeDrawing, true, new IDoodleListener() {
            @Override
            public void onSaved(IDoodle doodle, Bitmap bitmap, Runnable callback) { // 保存图片为jpg格式
                LogUtils.i("m1:-----doodle----onSaved");
                Thread thread1 = getMainLooper().getThread();
                Thread thread2 = Thread.currentThread();

                LogUtils.i("m1:-----doodle----doodleViewWrapper主线程ID: " + thread1.getId());
                LogUtils.i("m1:-----doodle----doodleViewWrapper当前线程ID: " + thread2.getId());
            }

            @Override
            public void onReady(IDoodle doodle) {
                LogUtils.i("-----doodle----onReady");
            }
        });

        mTouchGestureListener = new DoodleOnTouchGestureListener(mDoodleView, new DoodleOnTouchGestureListener.ISelectionListener() {

            IDoodleItemListener mIDoodleItemListener = new IDoodleItemListener() {
                @Override
                public void onPropertyChanged(int property) {

                }
            };

            @Override
            public void onSelectedItem(IDoodle doodle, IDoodleSelectableItem selectableItem, boolean selected) {

            }

            @Override
            public void onCreateSelectableItem(IDoodle doodle, float x, float y) {

            }

            @Override
            public void onCallScrollBegin(MotionEvent e) {

            }

            @Override
            public void onCallScrollEnd(MotionEvent e) {

            }

            @Override
            public void onCallScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                LogUtils.i("m1:滚动手指：distanceX: " + distanceX + ", distanceY:" + distanceY);
            }

        }) {
            @Override
            public void setSupportScaleItem(boolean supportScaleItem) {
                super.setSupportScaleItem(supportScaleItem);
            }
        };
        mTouchGestureListener.setSupportScale(false); //禁止放大缩小
        setSupportDoodle(false);
        setSupportTrans(false);


        mTouchGestureListener.setTouchType(DoodleOnTouchGestureListener.TOUCH_TYPE_ALL);
        IDoodleTouchDetector detector = new DoodleTouchDetector(this.getApplicationContext(), mTouchGestureListener);
        mDoodleView.setDefaultTouchDetector(detector);
        mDoodleView.setStartXy(true);
        mDoodleView.setColor(new DoodleColor(Color.BLACK));

        mDoodle.setIsDrawableOutside(mDoodleParams.mIsDrawableOutside);
        fl_revision_doodle.addView(mDoodleView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mDoodle.setDoodleMinScale(mDoodleParams.mMinScale);
        mDoodle.setDoodleMaxScale(mDoodleParams.mMaxScale);
        mDoodle.setZoomerScale(0.79f * 0.95f);


    }


    /**
     * 上传图片回调
     */
    UploadOss.OnUploadListener ossUploadListener = new UploadOss.OnUploadListener() {
        @Override
        public String uploadSuccess(String uploadFile, String localFile, OssParams ossParams) {
            Thread thread1 = getMainLooper().getThread();
            Thread thread2 = Thread.currentThread();
            LogUtils.i("-----doodle----OSSUploadListener主线程ID: " + thread1.getId());
            LogUtils.i("-----doodle----OSSUploadListener当前线程ID: " + thread2.getId());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {


                    if (localFile.contains(".mp3")) {
                        ossMp3Path = uploadFile;
                    } else if (localFile.contains(".txt")) {
                        ossTxtPath = uploadFile;
                    }
                    LogUtils.i("上传判断uploadSuccess： mSubmitCount = " + mSubmitCount + ", isSubmiting = " + isSubmiting +
                            ",ossmap=" + ossMp3Path + ",osstxt=" + ossTxtPath);
                    if (mSubmitCount > 0) {
                        mSubmitCount--;
                    }

                    /**
                     * 如果有笔记则需要条件判断
                     * 没笔迹则不需要
                     */
                    if (mSubmitCount == 0 && ossMp3Path != null && (isHasTrack?(ossTxtPath!=null):true)) {
                        hideSubmitDialog();
                        String pid = localFile.substring(localFile.lastIndexOf(File.separator) + 1, localFile.lastIndexOf("_"));
                        LogUtils.i("截取上传图片的pid：" + pid);

                        QuestionRevisionItem item = DBUtils.getInstance(RevisionDrawActivity.this).getQuestionRevisionByTag(pid);
                        if (item!=null){
                            item.setUploadAudioPath(ossMp3Path);
                            item.setUploadTrackPath(ossTxtPath);
                            DBUtils.getInstance(RevisionDrawActivity.this).updateQuestionRevisionItem(item);
                        }
                        isSubmitSuccess = true;
                        tv_revision_finish.setEnabled(true);
                        cancelRecording();
                    }
                }
            });
            return null;
        }

        @Override
        public String uploadFail(String uploadFile, String localFile, OssParams ossParams) {
            LogUtils.e("oss uploadFail");
            ToastUtil.initToast("保存失败，请检查网络是否异常");
            ossMp3Path = null;
            ossTxtPath = null;
            hideSubmitDialog();
            tv_revision_finish.setEnabled(true);
            return null;
        }
    };


    @Override
    public void revisionWrongQuestionResult(BaseResponse resp) {

    }

    @Override
    public void revisionWrongQuestionFail() {

    }


    /**
     * 包裹DoodleView，监听相应的设置接口，以改变UI状态
     */
    private class DoodleViewWrapper extends DoodleView {

        public DoodleViewWrapper(Context context, Bitmap bitmap, boolean optimizeDrawing, boolean isMask, IDoodleListener listener) {
            super(context, bitmap, optimizeDrawing, isMask, listener);
        }
    }

    private void setSupportDoodle(boolean isSupport) {
        if (mTouchGestureListener != null) {
            mTouchGestureListener.setSupportDoodle(isSupport);
        }
    }

    private void setSupportTrans(boolean isSupport) {
        if (mTouchGestureListener != null) {
            mTouchGestureListener.setSupportTrans(isSupport);
        }
    }

    /**
     * 保存方法
     */
    public void saveBitmap(Bitmap bitmap, String filePath) {
        File f = new File(filePath);
        if (f.exists()) {
            f.delete();
            //return;
        }
        String type = "";
        if ("PNG".equals(filePath.substring(filePath.lastIndexOf(".") + 1).toUpperCase())) {
            type = ".png";
        } else {
            type = ".jpg";
        }

        try {
            FileOutputStream out = new FileOutputStream(f);
            if (".png".equals(type)) {
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            } else {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            }

            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public Bitmap resizeImage(Bitmap bitmap, int width, int height) {
        int bmpWidth = bitmap.getWidth();
        int bmpHeight = bitmap.getHeight();

        float scaleWidth = ((float) width) / bmpWidth;
        float scaleHeight = ((float) height) / bmpHeight;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);

        return Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
    }

    @Override
    public boolean getIsBindTsdService() {
        return true;
    }

    @Override
    public TsdService.OnDataReceiveListener getTsdServiceDataReceiveListener() {
        return tsdListener;
    }


    /**
     * 录制说写订正
     */
    private void recordRevision() {
        if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_IDE) {
            startRecording();
        } else if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_START) {
            pauseRecording();
        } else if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_PAUSE) {
            resumeRecording();
        } else if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_COMPLETE) {
            ToastUtil.initToast("录音时间超过30分钟，请点击重录或完成");
        }
    }

    /**
     * 将笔迹写进文件
     *
     * @param
     */
    private void writeEventToFile(CoordinateInfo curDot) {
        if (!fileOperate()) {
            return;
        }
        if (curDot != null) {
            String action = "ACTION_DOWN";
            if (curDot.state == TsdService.PEN_COODINAT_MESSAGE) {
                action = "ACTION_MOVE";
            } else if (curDot.state == TsdService.PEN_UP_MESSAGE) {
                action = "ACTION_UP";
            }
            trackId++;
            TrackBean trackBean = new TrackBean(trackId, curDot.coordX, curDot.coordY, action, mRecorderTime, 1, true, fl_width, fl_height);
            lineWriteFile(trackFilePath, JsonUtils.toJson(trackBean));

        }
    }

    private void lineWriteFile(String filePath, String json) {
        try {
            FileWriter fw = new FileWriter(new File(filePath), true);
            //写入中文字符时会出现乱码
            BufferedWriter bw = new BufferedWriter(fw);
            //BufferedWriter  bw=new BufferedWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("E:/phsftp/evdokey/evdokey_201103221556.txt")), "UTF-8")));
            bw.write(json + "\r\n");
            bw.close();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private boolean fileOperate() {
        if (!FileUtils.isSdcardExist()) {
            ToastUtil.initToast("SD卡不存在");
            return false;
        }
        //String dirPath = getExternalFilesDir(null).getAbsolutePath();
        String dirPath = Constants.FILE_PATH;
        String mobile = SPUtils.getInstance().getString(Constants.USER_ID_KEY);
        if (StringUtil.isEmpty(mobile)) {
            LogUtils.e("出错了，手机号码不能为空");
            return false;
        }

        String voiceDirPath_temp = dirPath + File.separator + mobile + File.separator + "revision";
        File voiceDir = new File(voiceDirPath_temp);
        if (!voiceDir.exists()) {
            boolean mkdirs = voiceDir.mkdirs();
            if (!mkdirs) {
                LogUtils.e("创建失败voiceDir：" + mkdirs);
                return false;
            } else {
                LogUtils.i("创建成功voiceDir");
            }
        }
        voiceDirPath = voiceDirPath_temp;
        voiceFilePath = voiceDirPath + File.separator + examId + "_" + studentExamAnswerId + "_" + questionId + "_audio.mp3";
        trackFilePath = voiceDirPath + File.separator + examId + "_" + studentExamAnswerId + "_" + questionId + "_track.txt";
        return true;
    }

    /**
     * 开始录制
     */
    public void startRecording() {
        if (voiceRecorder.getRecordStatus() != VoiceRecorder.VOICE_RECORDER_IDE
                && voiceRecorder.getRecordStatus() != VoiceRecorder.VOICE_RECORDER_COMPLETE) {
            ToastUtil.initToast("不能点两次开始录制");
            return;
        }

        if (voiceFilePath == null) {
            return;
        }
        File trackFile = new File(trackFilePath);
        if (!trackFile.exists()) {
            try {
                trackFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        voiceRecorder.setVoiceFilePath(voiceFilePath);

        try {
            wakeLock.acquire();
            voiceRecorder.startRecording(this);
            onVoiceRecordingState(voiceRecorder.getRecordStatus());
        } catch (Exception e) {
            e.printStackTrace();
            if (wakeLock.isHeld())
                wakeLock.release();
            if (voiceRecorder != null)
                voiceRecorder.discardRecording();
            onVoiceRecordFail();
            ToastUtil.initToast("录音失败");
            return;
        }
    }

    private void onVoiceRecordFail() {
        //tv_recordStatus.setText("录音失败");
        initAudioView();
    }

    private void initAudioView() {
        iv_revision_playOrPause.setImageResource(R.drawable.ic_revision_start);
        tv_revision_Time.setText("00:00");
        mRecorderTime = 0;
        voiceRecorder.setRecorderStatus(VoiceRecorder.VOICE_RECORDER_IDE);
        tv_revision_finish.setEnabled(true);
    }

    //暂停录制
    private void pauseRecording() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (voiceRecorder.getRecordStatus() != VoiceRecorder.VOICE_RECORDER_START) {
                ToastUtil.initToast("只有在正在录制时，才能暂停");
                return;
            }
            voiceRecorder.pauseRecording();
            onVoiceRecordingState(voiceRecorder.getRecordStatus());
        }
    }

    //恢复录制
    private void resumeRecording() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (voiceRecorder.getRecordStatus() != VoiceRecorder.VOICE_RECORDER_PAUSE) {
                ToastUtil.initToast("只有在暂停录制时，才能恢复录制");
                return;
            }
            voiceRecorder.resumeRecording();
            onVoiceRecordingState(voiceRecorder.getRecordStatus());
        }
    }

    private void scrollBitmap() {


        float temp_y = TsdPenUtil.getRealX(mCurDot.coordY, mPic_h) * mDoodleView.getZoomerScale();
        LogUtils.i("m1: 滚动坐标到x=" + m_tran_x + ", y = " + temp_y +
                ", m_tran_x = " + 0  + ", m_tran_y = " + temp_y + "big_w=" + mDoodleView.getWidth() + "big_h=" + mDoodleView.getHeight());
        if (temp_y > (2 * mDoodleView.getHeight()) && fl_cur_height <= (2*mDoodleView.getHeight()))
        {
            fl_cur_height = mDoodleView.getHeight() * 3;
            mIsTran_y = true;
        }else if (temp_y > mDoodleView.getHeight() && temp_y < (2*mDoodleView.getHeight())
                &&  fl_cur_height != (2*mDoodleView.getHeight())){
            fl_cur_height = mDoodleView.getHeight() * 2;
            mIsTran_y = true;
        }else if (temp_y < mDoodleView.getHeight() && fl_cur_height > mDoodleView.getHeight()){
            fl_cur_height = mDoodleView.getHeight();
            mIsTran_y = true;
        }

        if (mIsTran_y && !isMove){
            mIsTran_y = false;
            m_tran_y = fl_cur_height - mDoodleView.getHeight();
            LogUtils.e(  "滚动距离=="  + -m_tran_y + "最终滚动==" + -m_tran_y);
            mTouchGestureListener.setDoodleTranslationXY(0,-m_tran_y);

        }
    }


    private void drawBitmap() {

        mTemp_x = (TsdPenUtil.getRealX(mCurDot.coordX, mPic_w) ) * mDoodleView.getZoomerScale();
        mTemp_y = (TsdPenUtil.getRealY(mCurDot.coordY, mPic_h) ) * mDoodleView.getZoomerScale()-m_tran_y ;

        LogUtils.i("m1: 绘制坐标：mTemp_x = " + mTemp_x + ", mTemp_y = " + mTemp_y + "coordX=" + mCurDot.coordX + ",coordY=" + mCurDot.coordY);
        if (mCurDot.state == TsdService.PEN_DOWN_MESSAGE) {
            isMove = false;
            mTouchGestureListener.r_onDown(mTemp_x, mTemp_y);
            mTouchGestureListener.r_onScrollBegin(mTemp_x, mTemp_y);
        } else if (mCurDot.state == TsdService.PEN_COODINAT_MESSAGE) {
            isMove = true;
            mTouchGestureListener.r_onScroll(mTemp_x, mTemp_y);
        } else if (mCurDot.state == TsdService.PEN_UP_MESSAGE) {
            isMove = false;
            mTouchGestureListener.r_onScrollEnd(mTemp_x, mTemp_y);
        }
    }


    private void onSetVolume(int volume, int second) {
        LogUtils.i("m1:" + "onSetVolume second ==" + second);
        if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_IDE) {
            runOnUiThread(() -> {
                tv_revision_Time.setText("00:00");
            });
            mRecorderTime = 0;
        } else {
            mRecorderTime = second;
            LogUtils.i("m1:" + "onSetVolume update tv ==" + ComUtil.stringForTime((int) (second)));
            runOnUiThread(() -> {
                tv_revision_Time.setText("" + ComUtil.stringForTime((int) (second)));
            });

        }
        //tv_recordVol.setText("音量：" + volume);

        if (second >= mMaxTime) {
            completeRecord(true);
        }
    }

    //完成录制
    private void completeRecord(boolean isMax) {
        if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_START
                || voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_PAUSE) {
            try {
                int length = stopRecoding();
                if (length > 0) {
                    onVoiceRecordComplete(getVoiceFilePath(), length, isMax);
                } else if (length == EMError.FILE_INVALID) {
                    onVoiceRecordFail();
                    ToastUtil.initToast("没有录音权限，录音失败");
                } else {
                    onVoiceRecordFail();
                    ToastUtil.initToast("录音时间太短，录音失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                // Toast.makeText(context, R.string.send_failure_please, Toast.LENGTH_SHORT).show();
            }
        } else if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_COMPLETE) {
            insertRevisionDao();
            uploadVideoFile();
        } else {
            ToastUtil.initToast("只有正在录制或者暂停录制时，才能点击完成录制");
        }

    }

    public int stopRecoding() {
        if (wakeLock.isHeld())
            wakeLock.release();
        return voiceRecorder.stopRecoding();
    }

    public String getVoiceFilePath() {
        return voiceRecorder.getVoiceFilePath();
    }


    /**
     * 将订正数据保存本地
     */
    private void insertRevisionDao(){
        String pid =  trackFilePath.substring(trackFilePath.lastIndexOf(File.separator) + 1, trackFilePath.lastIndexOf("_"));
        QuestionRevisionItem item = new QuestionRevisionItem(null, pid, voiceFilePath,
                trackFilePath, ossMp3Path, ossTxtPath, mRecorderTime, new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
        DBUtils.getInstance(RevisionDrawActivity.this).insertQuestionRevisionItem(item);
    }

    /**
     * 上传音频文件
     */
    private void uploadVideoFile() {
        isSubmiting = true;
        File txtFile = new File(trackFilePath);
        if (txtFile.exists()) {
            //如果文件大小大于0，说明有写笔迹
            if (txtFile.length() > 0){
                isHasTrack = true;
                mSubmitCount++;
                String path_pre = examId + "_" + studentExamAnswerId + "_" + questionId + "_track";
                final String uploadFileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "/" + path_pre + "_" + System.currentTimeMillis() + ".txt";
                UploadOss.getInstance().upload2OSS(uploadFileName, trackFilePath, ossUploadListener, null);
            }else {
                //没写笔迹
                isHasTrack = false;
            }
        } else {
            LogUtils.e("轨迹文件不存在，请检查是否有轨迹还是文件丢失");
        }
        File map3File = new File(voiceFilePath);
        if (map3File.exists()) {
            mSubmitCount++;
            String path_pre = examId + "_" + studentExamAnswerId + "_" + questionId + "_video";
            final String uploadFileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "/" + path_pre + "_" + System.currentTimeMillis() + ".mp3";
            UploadOss.getInstance().upload2OSS(uploadFileName, voiceFilePath, ossUploadListener, null);
        } else {
            ToastUtil.initToast("录音视频出错，录音文件丢失");
            LogUtils.e("录音视频出错，录音文件丢失");
            isSubmiting = false;
            cancelRecording();
        }


    }


    private void onVoiceRecordingState(int recordStatus) {
        if (recordStatus == VoiceRecorder.VOICE_RECORDER_IDE
                || recordStatus == VoiceRecorder.VOICE_RECORDER_COMPLETE
                || recordStatus == VoiceRecorder.VOICE_RECORDER_PAUSE) {
            iv_revision_playOrPause.setImageResource(R.drawable.ic_revision_start);
        } else if (recordStatus == VoiceRecorder.VOICE_RECORDER_START) {
            iv_revision_playOrPause.setImageResource(R.drawable.ic_revision_pause);
        }
    }


    private void onVoiceRecordComplete(String voiceFilePath, int voiceTimeLength, boolean isMax) {
        //tv_recordStatus.setText("完成录音");
        iv_revision_playOrPause.setImageResource(R.drawable.ic_revision_start);
        if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_IDE) {
            tv_revision_Time.setText("00:00");
            mRecorderTime = 0;
        } else {
            mRecorderTime = voiceTimeLength;
            tv_revision_Time.setText("" + ComUtil.stringForTime((int) (voiceTimeLength / 1000)));
        }
        if (isMax) {
            show_btn_dialog(DIALOG_TYPE_MAXTIME);
        } else {
            insertRevisionDao();
            uploadVideoFile();
        }
    }

    private void audioExplainClose() {
        //关闭不保存文件
        deleteRecordFile();
        cancelRecording();
    }



    private void deleteRecordFile(){
        deleteLocalFile(trackFilePath);
        deleteLocalFile(voiceFilePath);
    }


    private void deleteLocalFile(String path){
        if (path==null)return;
        File file = new File(path);
        if (file.exists()){
            file.delete();
        }
    }

    private void cancelRecording() {
        discardRecording();

        if (isSubmitSuccess) {
            BaseEvent baseEvent = new BaseEvent();
            baseEvent.setCode(Constants.ConstData.REVISION_RECORD_FINISH);
            baseEvent.setData(getRevisionQuestionData());
            EventBus.getDefault().post(baseEvent);
        }
        finish();
    }


    /**
     * 提交订正请求数据
     */
    private RevisionQuestionReq.RevisionBean getRevisionQuestionData() {
        RevisionQuestionReq.RevisionBean revisionBean = new RevisionQuestionReq.RevisionBean(
                studentExamAnswerId, questionId,
                ossMp3Path + "," + (ossTxtPath == null?"":ossTxtPath), 2, String.valueOf(mRecorderTime), 1,
                subjectId);
        return revisionBean;
    }

    public void discardRecording() {
        if (wakeLock.isHeld())
            wakeLock.release();
        try {
            // stop recording
            if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_START
                    || voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_PAUSE
                    || voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_COMPLETE) {
                voiceRecorder.discardRecording();
//                onVoiceRecordFail();
            }
        } catch (Exception e) {
        }
    }

    private void audioExplainComplete() {
        tv_revision_finish.setEnabled(false);
        completeRecord(false);
    }

    private void audioExplainMaxTime() {
        insertRevisionDao();
        uploadVideoFile();
    }

    private void show_btn_dialog(final int type) {
        String title = "";
        String tip = "";
        if (type == DIALOG_TYPE_CLOSE) {
            title = "退出";
            tip = "退出后数据将丢失，确定退出吗？";
        } else if (type == DIALOG_TYPE_COMPLETE) {
            title = "完成";
            tip = "确定完成录制吗？";
        } else if (type == DIALOG_TYPE_MAXTIME) {
            title = "完成";
            tip = "达到最大录制时间，确定完成录制吗？";
        }

        DialogXUtil.customDialogShow(tip, title, "取消", new DialogXUtil.OnDialogXListen() {
            @Override
            public void onListenDialogOk() {
                if (type == DIALOG_TYPE_CLOSE) {
                    audioExplainClose();
                } else if (type == DIALOG_TYPE_COMPLETE) {
                    if (!ComUtil.isNetworkConnected()){
                        ToastUtil.initToast("网络已断开，请先检查网络");
                        return;
                    }
                    showSubmitDialog();
                    audioExplainComplete();
                } else if (type == DIALOG_TYPE_MAXTIME) {
                    if (!ComUtil.isNetworkConnected()){
                        ToastUtil.initToast("网络已断开，请先检查网络");
                        return;
                    }
                    audioExplainMaxTime();
                }
            }

            @Override
            public void onListenDialogCancel() {
                tv_revision_finish.setEnabled(true);
            }

            @Override
            public void onListenDialogClose() {

            }
        });
    }


    public void showSubmitDialog() {
        DialogXUtil.waitDialogShow( "正在保存...");
    }

    public void hideSubmitDialog() {
        DialogXUtil.waitDialogDismiss();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (voiceRecorder.getRecordStatus() == VoiceRecorder.VOICE_RECORDER_START) {
            pauseRecording();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        setStopWrite(true);
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行
    public void onEventReceived(BaseEvent event) {

    }



    public void setStopWrite(boolean stopWrite) {
        this.stopWrite = stopWrite;
    }

    private class WriteThread extends Thread{

        CoordinateInfo coordinateInfo;
        @Override
        public void run() {
            while(!stopWrite){
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                while (!mSaveLineDots.isEmpty()){
                    coordinateInfo = mSaveLineDots.poll();
                    writeEventToFile(coordinateInfo);
                }
            }

        }
    }
}
